package com.ccb.sc.goods.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ccb.sc.goods.controller.query.AppGoodsQueryParam;
import com.ccb.sc.goods.controller.query.AppGoodsSearchParam;
import com.ccb.sc.goods.convert.AppGoodsConvert;
import com.ccb.sc.goods.enums.OrderBy;
import com.ccb.sc.goods.mapper.AppGoodsMapper;
import com.ccb.sc.goods.service.IAppGoodsService;
import com.ccb.sc.goods.vo.AppGoodsListVo;
import com.ccb.sc.goods.vo.AppGoodsVo;
//psl import com.ccb.sc.common.bind.exception.BizException;
import com.ccb.sc.common.bind.page.PageVo;
import com.ccb.sc.common.bind.query.Filter;
import com.ccb.sc.common.code.BizCodeFace;
import com.ccb.sc.common.code.ErrorCode;
import com.ccb.sc.common.modules.goods.entity.*;
import com.ccb.sc.common.modules.goods.enums.GoodsStatus;
import com.ccb.sc.common.modules.goods.enums.GoodsType;
import com.ccb.sc.common.modules.goods.mapper.BrandMapper;
import com.ccb.sc.common.modules.goods.mapper.CategoryMapper;
import com.ccb.sc.common.modules.goods.service.IGoodsCommentService;
import com.ccb.sc.common.modules.goods.service.IGoodsService;
import com.ccb.sc.common.modules.goods.vo.GoodsCommentStatVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ken
 * @version 1.0
 * @date 2020-09-21
 */
@Service
public class AppGoodsServiceImpl extends ServiceImpl<AppGoodsMapper, Goods> implements IAppGoodsService {

    private IGoodsService goodsService;
    private BrandMapper brandMapper;
    private CategoryMapper categoryMapper;
    private IGoodsCommentService goodsCommentService;

    @Override
    public PageVo<AppGoodsListVo> list(AppGoodsQueryParam queryParam) {
        Page<Goods> page = new Page<>(queryParam.getCurrent(), queryParam.getPageSize());
        AppGoodsMapper.QueryParam params = new AppGoodsMapper.QueryParam();
        AppGoodsSearchParam searchParam = new AppGoodsSearchParam();
        searchParam.setOrderBy(OrderBy.lastOnsaleTime);
        searchParam.setDirection(OrderBy.Direction.desc);
        searchParam.setCurrent(queryParam.getCurrent());
        searchParam.setPageSize(queryParam.getPageSize());
        return select(searchParam, params);
    }

    @Override
    public PageVo<AppGoodsListVo> search(AppGoodsSearchParam searchParam) {
        AppGoodsMapper.QueryParam params = new AppGoodsMapper.QueryParam();
        params.setCategory(0);
        return select(searchParam, params);
    }

    @Override
    public PageVo<AppGoodsListVo> exchange(AppGoodsSearchParam searchParam, Long memberId) {
        AppGoodsMapper.QueryParam params = new AppGoodsMapper.QueryParam();
        params.setCategory(1);
        params.setMemberId(memberId);
        return select(searchParam, params);
    }

    @Override
    public PageVo<AppGoodsListVo> hot() {
        AppGoodsSearchParam searchParam = new AppGoodsSearchParam();
        searchParam.setCurrent(1);
        searchParam.setPageSize(10);
        searchParam.setOrderBy(OrderBy.sales);
        searchParam.setDirection(OrderBy.Direction.desc);
        AppGoodsMapper.QueryParam params = new AppGoodsMapper.QueryParam();
        params.setCategory(2);
        return select(searchParam, params);
    }

    @Override
    public PageVo<AppGoodsListVo> restock(AppGoodsSearchParam searchParam) {
        AppGoodsMapper.QueryParam params = new AppGoodsMapper.QueryParam();
        params.setCategory(3);
        return select(searchParam, params);
    }

    @Override
    public PageVo<AppGoodsListVo> newStock(AppGoodsSearchParam searchParam) {
        AppGoodsMapper.QueryParam params = new AppGoodsMapper.QueryParam();
        params.setCategory(4);
        return select(searchParam, params);
    }

    private PageVo<AppGoodsListVo> select(AppGoodsSearchParam searchParam, AppGoodsMapper.QueryParam params) {
        Page<Goods> page = new Page<>(searchParam.getCurrent(), searchParam.getPageSize());
        if (StringUtils.hasText(searchParam.getKey())) {
            params.setKey(Filter.LikeValue.both(searchParam.getKey()));
        }

        if (searchParam.getOrderBy() != null) {
            switch (searchParam.getOrderBy()) {
                case sales:
                    params.setOrderBy("g.sales");
                    break;
                case lastOnsaleTime:
                    params.setOrderBy("g.last_onsale_time");
                    break;
                case price:
                    params.setOrderBy("g.exchange_points");
                    break;
                default:
                    break;
            }
        }
        if (searchParam.getDirection() != null) {
            params.setDirection(searchParam.getDirection().name());
        }
        Page<AppGoodsListVo> records = this.getBaseMapper().selectByQueryParam(page, params);

        return PageVo.create(searchParam.getCurrent(), searchParam.getPageSize(), records.getTotal(), records.getRecords());
    }

    @Override
    public AppGoodsVo detail(Long goodsId, HttpServletRequest request) {
        Goods goods = this.getById(goodsId);
        if (goods == null || !GoodsStatus.ON_SALE.equals(goods.getStatus())) {
            //psl throw new BizException(BizCodeFace.createBizCode(ErrorCode.DATE_NULL).message("商品已下架"));
        }
        AppGoodsVo goodsVo = AppGoodsConvert.INSTANCE.entity2Vo(goods);
        Brand brand = this.brandMapper.selectById(goods.getBrandId());
        if (brand != null) {
            goodsVo.setBrandName(brand.getName());
        }
        Category category = this.categoryMapper.selectById(goods.getCategoryId());
        if (category != null) {
            goodsVo.setCategoryName(category.getName());
        }
        List<GoodsCarousel> carousels = this.goodsService.getGoodsCarousels(goodsId);
        if (!CollectionUtils.isEmpty(carousels)) {
            goodsVo.setCarousels(carousels.stream().map(GoodsCarousel::getUrl).collect(Collectors.toList()));
        }
        List<GoodsSpecs> specs = this.goodsService.getGoodsSpecsByGoodsId(goodsId);
        if (!CollectionUtils.isEmpty(specs)) {
            goodsVo.setSpecs(AppGoodsConvert.INSTANCE.goodsSpec2VoBatch(specs));
        }
        GoodsDetail goodsDetail = this.goodsService.getGoodsDetailByGoodsId(goodsId);
        if (goodsDetail != null) {
            goodsVo.setDetail(goodsDetail.getDetail());
        }

        // 评论统计
        GoodsCommentStatVo comment = this.goodsCommentService.getGoodsDetailCommentStat(goodsId, GoodsType.POINTS_GOODS);
        goodsVo.setComment(comment);

        goods.setViews(goods.getViews() + 1);
        this.updateById(goods);

        return goodsVo;
    }

    @Override
    public List<AppGoodsListVo> recommendList(Long goodsId) {
        int recommendSize = 4;
        // 根据商品id生成推荐商品
        if (goodsId != null) {
            Goods goods = this.getById(goodsId);
        }

        Page<Goods> page = new Page<>(1, recommendSize + 1);
        AppGoodsMapper.QueryParam params = new AppGoodsMapper.QueryParam();
        params.setOrderBy("g.sales");
        params.setDirection(OrderBy.Direction.desc.name());
        Page<AppGoodsListVo> records = this.getBaseMapper().selectByQueryParam(page, params);
        List<AppGoodsListVo> recommendList = records.getRecords();
        // 如果同一家店铺商品小于3个，再查找同一商城同一类下的商品
        if (recommendList.size() < recommendSize) {
            Page<Goods> categoryPage = new Page<>(1, recommendSize - recommendList.size());
            AppGoodsMapper.QueryParam categoryParams = new AppGoodsMapper.QueryParam();
            categoryParams.setOrderBy("g.sales");

            categoryParams.setDirection(OrderBy.Direction.desc.name());
            Page<AppGoodsListVo> categoryRecords = this.getBaseMapper().selectByQueryParam(categoryPage, categoryParams);
            if (!CollectionUtils.isEmpty(categoryPage.getRecords())) {
                recommendList.addAll(categoryRecords.getRecords());
            }
            // 如果两次总商品小于3个，再查找全品类下的商品
            if (recommendList.size() < recommendSize) {
                Page<Goods> allPage = new Page<>(1, recommendSize - recommendList.size());
                Page<AppGoodsListVo> allRecords = this.getBaseMapper().selectByQueryParam(allPage, categoryParams);
                recommendList.addAll(allRecords.getRecords());
            }
        }
        recommendList.removeIf(goodsListVo -> goodsListVo.getId().equals(goodsId));
        return recommendList;
    }

    @Override
    public List<AppGoodsListVo> hotSearchList() {
        Page<Goods> page = new Page<>(1, 10);
        AppGoodsMapper.QueryParam params = new AppGoodsMapper.QueryParam();
        params.setOrderBy("g.sales");
        params.setDirection(OrderBy.Direction.desc.name());
        Page<AppGoodsListVo> records = this.getBaseMapper().selectByQueryParam(page, params);
        return records.getRecords();
    }

    @Autowired
    public void setGoodsService(IGoodsService goodsService) {
        this.goodsService = goodsService;
    }

    @Autowired
    public void setBrandMapper(BrandMapper brandMapper) {
        this.brandMapper = brandMapper;
    }

    @Autowired
    public void setCategoryMapper(CategoryMapper categoryMapper) {
        this.categoryMapper = categoryMapper;
    }

    @Autowired
    public void setGoodsCommentService(IGoodsCommentService goodsCommentService) {
        this.goodsCommentService = goodsCommentService;
    }
}
